package server

import (
	"bytes"
	"common/database/config"
	"context"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"go.uber.org/zap"
	"log"
	"strconv"
	"user_srv/internal/models/dao"
	user "user_srv/proto"
)

func Sync(user *dao.User) {
	// Build the request body.
	data, err := json.Marshal(&user)
	if err != nil {
		log.Fatalf("Error marshaling document: %s", err)
	}

	// Set up the request object.
	req := esapi.IndexRequest{
		Index:      "week2",
		DocumentID: strconv.Itoa(int(user.ID)),
		Body:       bytes.NewReader(data),
		Refresh:    "true",
	}

	// Perform the request with the client.
	res, err := req.Do(context.Background(), config.Elastic)
	if err != nil {
		zap.S().Fatalf("Error getting response: %s", err)
	}
	defer res.Body.Close()
}

func GetSync(keyWord string) []*user.Doctor {
	var buf bytes.Buffer
	query := map[string]interface{}{}
	if keyWord != "" {
		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match": map[string]interface{}{
					"name": keyWord,
				},
			},
		}
	} else {
		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match_all": map[string]interface{}{},
			},
		}
	}
	if err := json.NewEncoder(&buf).Encode(query); err != nil {
		log.Fatalf("Error encoding query: %s", err)
	}
	// Perform the search request.
	res, err := config.Elastic.Search(
		config.Elastic.Search.WithContext(context.Background()),
		config.Elastic.Search.WithIndex("week2"),
		config.Elastic.Search.WithBody(&buf),
		config.Elastic.Search.WithTrackTotalHits(true),
		config.Elastic.Search.WithPretty(),
	)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	defer res.Body.Close()
	r := map[string]interface{}{}
	if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
		log.Fatalf("Error parsing the response body: %s", err)
	}
	var sli []*user.Doctor
	for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) {
		hits := hit.(map[string]interface{})["_source"].(map[string]interface{})
		one := &user.Doctor{
			Name:      hits["name"].(string),
			Image:     hits["image"].(string),
			Where:     int64(hits["where"].(float64)),
			ObjRoom:   int64(hits["objRoom"].(float64)),
			Job:       int64(hits["job"].(float64)),
			Title:     int64(hits["title"].(float64)),
			NumPrice:  float32(hits["numPrice"].(float64)),
			LookPrice: float32(hits["lookPrice"].(float64)),
			Cont:      hits["cont"].(string),
		}
		sli = append(sli, one)
	}
	return sli
}
